package org.monkey.common.constant.util;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

public class DataUtil {

  public static <T> void colForeach(Collection<T> ts, Consumer<T> consumer) {
    ts.forEach(consumer);
  }

  public static <T, R> List<R> colTypeChange(Collection<T> ts, Function<T, R> function) {
    if (isNotEmpty(ts)) {
      return ts.stream().map(function).collect(Collectors.toList());
    } else {
      return new ArrayList<>();
    }
  }

  public static <T, K> Map<K, T> colToMap(Collection<T> ts, Function<T, K> function) {
    if (isNotEmpty(ts)) {
      return ts.stream().collect(Collectors.toMap(function, t -> t));
    }else{
      return new HashMap<>();
    }
  }

  public static <T, K> Map<K, List<T>> colGroup(Collection<T> ts, Function<T, K> function) {
    return ts.stream().collect(Collectors.groupingBy(function));
  }

  public static <T, R, P> Map<R, List<P>> colGroup(Collection<T> ts, Function<T, R> keyFun,
      Function<T, P> valueFun) {
    return ts.stream().collect(Collectors.groupingBy(keyFun, Collectors.mapping(valueFun::apply, Collectors.toList())));
  }

  public static <T, K> Map<K, Long> colGroupCount(Collection<T> ts, Function<T, K> function) {
    return ts.stream().collect(Collectors.groupingBy(function, Collectors.counting()));
  }

  public static <T, U extends Comparable<? super U>> List<T> distinct(
      Collection<T> ts, Function<? super T, ? extends U> keyExtractor) {
    return ts.stream().collect(
        Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<T>(Comparator.comparing(keyExtractor))), ArrayList::new));
  }

  public static <T> List<T> listSub(List<T> ts, int start, int end) {
    if (start == -1) {
      return ts;
    }
    if (ts.isEmpty() || ts.size() < start) {
      return new ArrayList<>();
    } else {
      if (ts.size() < end) {
        return ts.subList(start, ts.size());
      } else {
        return ts.subList(start, end);
      }
    }
  }

  public static <T> boolean isEmpty(Collection<T> ts) {
    return ts == null || ts.size() == 0;
  }

  public static <T> boolean isNotEmpty(Collection<T> ts) {
    return ts != null && ts.size() > 0;
  }
}
